package com.coderman.modelfly.utils;

import com.coderman.modelfly.Constants;
import com.coderman.modelfly.config.AnnotationConfig;
import com.coderman.modelfly.config.BeanConfig;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.*;

/**
 * Created by ${fanchunshuai} on 2017-9-15.
 * @author 58
 * @version: V1.0
 * @Desc:
 * @Copyright (c) 2017 58到家-版权所有
 */
public class Dom4JUtils {
    /**
     * 读取bean配置
     * @param beanModel   beanEntity/beanDto
     * @return
     * @throws Exception
     */
    public static BeanConfig readBeanConfig(String beanModel,String configPath) throws Exception {
        BeanConfig config  = new BeanConfig();

        Map<String,Object> map = getConfigMap(beanModel,configPath);

        config.setExtendsClazz((String) map.get(beanModel + ".class.extendsClazz"));
        config.setImplementsClazz((String) map.get(beanModel + ".class.implementsClazz"));
        config.setPackageName((String) map.get(beanModel +".class.packageName"));
        config.setPreffix((String) map.get(beanModel + ".class.preffix"));
        config.setSuffix((String) map.get(beanModel + ".class.suffix"));
        config.setImportClazz((List<String>)map.get(beanModel + ".class.importClazz"));

        config.setClazzPath((String) map.get(beanModel + ".classPath"));


        config.setAuthor((String) map.get(beanModel + ".desc.author"));
        config.setCopyright((String) map.get(beanModel + ".desc.copyright"));
        config.setVersion((String) map.get(beanModel + ".desc.version"));


        //设置类注解
        AnnotationConfig clazzConfig = new AnnotationConfig();
        clazzConfig.setAnnotionName((String) map.get(beanModel + ".annotation.class.name"));
        clazzConfig.setAttributeName((String) map.get(beanModel + ".annotation.class.attr.name"));
        clazzConfig.setValueModel((String) map.get(beanModel + ".annotation.class.attr.valueModel"));
        System.out.println("clazzConfig = "+clazzConfig.toString());

        config.setClazzAnnotationConfig(clazzConfig);

        if(!Constants.BEAN_DTO.equals(beanModel)){
            //设置id注解
            AnnotationConfig idConfig = new AnnotationConfig();
            idConfig.setAnnotionName((String) map.get(beanModel + ".annotation.field.id"));
            config.setIdAnnotationConfig(idConfig);
        }


        //设置属性注解
        //设置类注解
        AnnotationConfig fieldConfig = new AnnotationConfig();
        fieldConfig.setAnnotionName((String) map.get(beanModel + ".annotation.field.name"));
        fieldConfig.setAttributeName((String) map.get(beanModel + ".annotation.field.attr.name"));
        fieldConfig.setValueModel((String) map.get(beanModel + ".annotation.field.attr.valueModel"));

        config.setFieldAnnotationConfig(fieldConfig);

        return config;
    }



    /*public static BeanConfig readBeanDtoConfig() throws Exception {
        BeanConfig config  = new BeanConfig();
        Map<String,Object> map = getConfigMap("beanDto");

        config.setExtendsClazz((String) map.get("beanDto.class.extendsClazz"));
        config.setImplementsClazz((String) map.get("beanDto.class.implementsClazz"));
        config.setPackageName((String) map.get("beanDto.class.packageName"));
        config.setPreffix((String) map.get("beanDto.class.preffix"));
        config.setSuffix((String) map.get("beanDto.class.suffix"));
        config.setImportClazz((List<String>)map.get("beanDto.class.importClazz"));

        config.setClazzPath((String) map.get("beanDto.classPath"));


        config.setAuthor((String) map.get("beanDto.desc.auther"));
        config.setCopyright((String) map.get("beanDto.desc.copyright"));
        config.setVersion((String) map.get("beanDto.desc.version"));

        return config;
    }*/



    private static Map<String,Object> getConfigMap(String configNodeName,String configPath) throws DocumentException {
        Map<String,Object> map = new HashMap<String, Object>();

        System.out.println(configPath+"\\model.xml"+"--------------------------------");
        //InputStream is= Dom4JUtils.class.getClassLoader().getResourceAsStream(configPath+"\\model.xml");

        InputStream is= null;
        try {
            is = new FileInputStream(new File(configPath+"\\model.xml"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        SAXReader reader = new SAXReader();
        Document document = reader.read(is);

        //获取根节点元素对象
        Element root = document.getRootElement();

        Node node = root.selectSingleNode(configNodeName);
        Node classPathNode = node.selectSingleNode("clazzPath");
        Node annotation = node.selectSingleNode("annotation");


        Node desc = node.selectSingleNode("desc");
        Node nodeClazz = node.selectSingleNode("clazz");
        //类名前缀
        Node preffix = nodeClazz.selectSingleNode("preffix");

        Node suffix = nodeClazz.selectSingleNode("suffix");
        Node packageName = nodeClazz.selectSingleNode("packageName");
        Node extendsClazz = nodeClazz.selectSingleNode("extendsClazz");
        Node implementsClazz = nodeClazz.selectSingleNode("implementsClazz");

        Node importClazz = nodeClazz.selectSingleNode("importClazz");

        List<Node> nodeList = importClazz.selectNodes("value");
        List<String> importClassList = new ArrayList<String>();

        for (Node nodeValue : nodeList){
            importClassList.add(nodeValue.getStringValue());
        }


        Node  author =  desc.selectSingleNode("author");
        Node  version =  desc.selectSingleNode("version");
        Node copyright =  desc.selectSingleNode("copyright");


        //读取类注解
        Node classAnnotation = annotation.selectSingleNode("class");
        Node annotationInfo = classAnnotation.selectSingleNode("annotation");
        String name = annotationInfo.selectSingleNode("name").getStringValue();
        String attrName = annotationInfo.selectSingleNode("attr").selectSingleNode("name").getStringValue();
        String valueModel = annotationInfo.selectSingleNode("attr").selectSingleNode("valueModel").getStringValue();
        System.out.println("valueModel = "+valueModel+",attrName = "+attrName);


        Node fieldAnnotation = annotation.selectSingleNode("field");
        if(!Constants.BEAN_DTO.equals(configNodeName)){
            //读取属性注解
            Node idAnnotationInfo = fieldAnnotation.selectSingleNode("id");
            String idAnnotation = idAnnotationInfo.selectSingleNode("value").getStringValue();
            map.put(configNodeName + ".annotation.field.id",idAnnotation);

        }


        String annotationName = fieldAnnotation.selectSingleNode("normal").selectSingleNode("name").getStringValue();
        String annotationAttrName = fieldAnnotation.selectSingleNode("normal").selectSingleNode("attr").selectSingleNode("name").getStringValue();
        String annotationAttrValue = fieldAnnotation.selectSingleNode("normal").selectSingleNode("attr").selectSingleNode("valueModel").getStringValue();


        map.put(configNodeName + ".class.preffix",preffix.getStringValue());
        map.put(configNodeName + ".class.suffix",suffix.getStringValue());
        map.put(configNodeName + ".class.extendsClazz",extendsClazz.getStringValue());
        map.put(configNodeName + ".class.packageName",packageName.getStringValue());
        map.put(configNodeName + ".class.implementsClazz",implementsClazz.getStringValue());
        map.put(configNodeName + ".class.importClazz",importClassList);

        map.put(configNodeName + ".desc.author",author.getStringValue());
        map.put(configNodeName + ".desc.version",version.getStringValue());
        map.put(configNodeName + ".desc.copyright",copyright.getStringValue());

        map.put(configNodeName + ".classPath",classPathNode.getStringValue());

        //配置类注解
        map.put(configNodeName + ".annotation.class.name",name);
        map.put(configNodeName + ".annotation.class.attr.name",attrName);
        map.put(configNodeName + ".annotation.class.attr.valueModel",valueModel);

        //配置属性注解
        map.put(configNodeName + ".annotation.field.name",annotationName);
        map.put(configNodeName + ".annotation.field.attr.name",annotationAttrName);
        map.put(configNodeName + ".annotation.field.attr.valueModel",annotationAttrValue);

        System.out.println(map.toString());
        return map;

    }


    public static void main(String[] args) {
        try {
            Dom4JUtils.getConfigMap("beanDto","E:\\tmp\\modelfly");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



}
